package com.zhongli.devplatform.service.impl.sys;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhongli.devplatform.bean.SecurityHelper;
import com.zhongli.devplatform.dto.sys.ChapterExercisesDTO;
import com.zhongli.devplatform.dto.student.CommitAnswerDTO;
import com.zhongli.devplatform.dto.ErrorRateDto;
import com.zhongli.devplatform.mapper.sys.*;
import com.zhongli.devplatform.po.sys.*;
import com.zhongli.devplatform.service.imp.sys.ReadChapterExercisesService;
import com.zhongli.devplatform.service.imp.sys.ReadChapterExercisesTopicService;
import com.zhongli.devplatform.service.imp.sys.ReadTopicService;
import com.zhongli.devplatform.utils.BeanCopierUtil;
import com.zhongli.devplatform.vo.TopicVO;
import com.zhongli.devplatform.vo.sys.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.text.NumberFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wy
 * @since 2020/7/31
 */
@Service
public class ReadChapterExercisesServiceImpl extends ServiceImpl<ReadChapterExercisesMapper, ReadChapterExercisesPO> implements ReadChapterExercisesService {

    @Resource
    private ReadChapterExercisesMapper chapterExercisesMapper;

    @Resource
    private ReadChapterExercisesTopicService chapterExercisesTopicService;

    @Resource
    private ReadChapterExercisesTopicMapper ChapterExercisesTopicMapper;

    @Resource
    private ReadKnowledgePointMapper knowledgePointMapper;
    @Resource
    private ReadTopicService topicService;

    @Resource
    private ReadChapterMapper chapterMapper;
    @Resource
    private ReadSubjectMapper subjectMapper;

    /**
     * 核对答案 返回比对
     * @param exercisesDTO {@link ChapterExercisesDTO}
     * @return 核对结果
     */
    @Override
    public ReadChapterExercisesPO checkAnswer(ChapterExercisesDTO exercisesDTO) {
        List<ReadChapterExercisesTopicPO> exercisesTopics = chapterExercisesTopicService.list(new QueryWrapper<ReadChapterExercisesTopicPO>()
                .eq("chapter_exercises_id", exercisesDTO.getChapterExercisesId()));
        HashMap<Integer, ReadChapterExercisesTopicPO> map = new HashMap<>();
        exercisesTopics.forEach(item-> map.put(item.getTopicId(),item));
        //提交的答案
        List<CommitAnswerDTO> commitAnswer = exercisesDTO.getTopics();
        //跟新答案到数据库
        commitAnswer.forEach(commitAnswerDTO -> {
            ReadChapterExercisesTopicPO exercisesTopicPO = map.get(commitAnswerDTO.getId());
            exercisesTopicPO.setCommitAnswer(commitAnswerDTO.getCommitAnswer());
            if (StringUtils.hasLength(exercisesTopicPO.getCorrectAnswer())) {
                exercisesTopicPO.setStatus(exercisesTopicPO.getCorrectAnswer().equals(commitAnswerDTO.getCommitAnswer()));
            }else {
                exercisesTopicPO.setStatus(true);
            }
            chapterExercisesTopicService.update(exercisesTopicPO
                    ,new QueryWrapper<ReadChapterExercisesTopicPO>()
                            .ge("chapter_exercises_id",exercisesDTO.getChapterExercisesId())
                            .eq("topic_id",commitAnswerDTO.getId()));
        });
        int totalCount = exercisesTopics.size();
        //正确的个数
        long count = exercisesTopics.stream().filter(ReadChapterExercisesTopicPO::getStatus).count();

        ReadChapterExercisesPO exercisesPO = new ReadChapterExercisesPO();
        exercisesPO.setId(exercisesDTO.getChapterExercisesId());
        exercisesPO.setEndTime(new Date());
        exercisesPO.setCorrectNum((int) count);
        exercisesPO.setErrorNum(totalCount-exercisesPO.getCorrectNum());

        // 创建一个数值格式化对象
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        String format = numberFormat.format((float) exercisesPO.getCorrectNum() / (float) totalCount);
        exercisesPO.setCorrectRate(Float.valueOf(format));
        chapterExercisesMapper.updateById(exercisesPO);
        return chapterExercisesMapper.selectOne(new QueryWrapper<ReadChapterExercisesPO>()
                .eq("id",exercisesDTO.getChapterExercisesId())
                .eq("student_id", SecurityHelper.getCurrentUserId()));
    }

    /**
     * @param currentUserId 当前学生id
     * @return 错题科目
     */
    @Override
    public List<SubjectVO> getAllWrongSubjects(Integer currentUserId) {
        List<Integer> knowledgePointIds = getKnowledgePointIds(currentUserId);
        if (knowledgePointIds == null) return new ArrayList<>();
        List<ReadKnowledgePointPO> knowledgePoints = knowledgePointMapper.selectBatchIds(knowledgePointIds);
        List<Integer> chapterIds= knowledgePoints
                .stream()
                .map(ReadKnowledgePointPO::getChapterId)
                .distinct()
                .collect(Collectors.toList());
        List<ReadChapterPO> chapters = chapterMapper.selectBatchIds(chapterIds);
        List<Integer> subjectIds = chapters.stream().map(ReadChapterPO::getSubjectId).distinct().collect(Collectors.toList());
        if (subjectIds.isEmpty()) return new ArrayList<>();
        return subjectMapper.selectBatchAndStatus(subjectIds);//subjectMapper.selectBatchIds(subjectIds);
    }

    /**
     * 所以的错题章节
     * @param currentUserId 当前学生id
     * @param subjectId 科目id
     * @return 结果
     */
    @Override
    public List<ReadChapterPO> getAllWrongChapter(Integer currentUserId, Integer subjectId) {
        List<Integer> knowledgePointIds = getKnowledgePointIds(currentUserId);
        List<ReadKnowledgePointPO> knowledgePoints = knowledgePointMapper.selectBatchIds(knowledgePointIds);
        List<Integer> chapterIds= knowledgePoints
                .stream()
                .map(ReadKnowledgePointPO::getChapterId)
                .distinct()
                .collect(Collectors.toList());
        return chapterMapper.selectList(new QueryWrapper<ReadChapterPO>().eq("subject_id",subjectId).in("id",chapterIds));
    }

    /**
     * 所以的错题知识点
     * @param currentUserId 当前学生id
     * @param chapterId 章节id
     * @return 当前章节id 下的所以的错题知识点
     */
    @Override
    public List<ReadKnowledgePointPO> getAllWrongKnowledgePoint(Integer currentUserId, Integer chapterId) {
        List<Integer> knowledgePointIds = getKnowledgePointIds(currentUserId);
        return knowledgePointMapper.selectList(new QueryWrapper<ReadKnowledgePointPO>()
                        .eq("chapter_id",chapterId)
                        .in("id",knowledgePointIds));
    }

    /**
     * 所以的错题
     * @param currentUserId 当前学生id
     * @param knowledgeId 知识点id
     * @return 当前知识点id 下的所以的错题知识点
     */
    @Override
    public List<TopicVO> getAllWrongTopic(Integer currentUserId, Integer knowledgeId) {
        ReadChapterExercisesPO chapterExercise= chapterExercisesMapper
                .selectOne(new QueryWrapper<ReadChapterExercisesPO>()
                .eq("student_id", currentUserId)
                .eq("knowledge_id",knowledgeId));
        /*List<Integer> chapterExerciseIds = chapterExercises
                .stream()
                .map(ReadChapterExercisesPO::getId)
                .collect(Collectors.toList());*/
        //List<Integer> topicIds = ChapterExercisesTopicMapper.selectWrongTopicIds(chapterExerciseIds);
        return ChapterExercisesTopicMapper.selectWrongTopic(chapterExercise.getId());
    }

    /**
     * 根据当前用户获取 所有的错题知识点ids
     * @param currentUserId 前用户
     * @return 错题知识点ids
     */
    private List<Integer> getKnowledgePointIds(Integer currentUserId){
        List<ReadChapterExercisesPO> chapterExercises= chapterExercisesMapper
                .selectList(new QueryWrapper<ReadChapterExercisesPO>().eq("student_id", currentUserId));
        List<Integer> chapterExerciseIds = chapterExercises
                .stream()
                .map(ReadChapterExercisesPO::getId)
                .collect(Collectors.toList());
        if(chapterExerciseIds.isEmpty()) return new ArrayList<>();
        List<Integer> topicIds = ChapterExercisesTopicMapper.selectWrongTopicIds(chapterExerciseIds);
        if(topicIds.isEmpty()) return new ArrayList<>();
        List<ReadTopicPO> list = topicService.listByIds(topicIds);
        return list.stream().map(ReadTopicPO::getKnowledgeId).distinct().collect(Collectors.toList());
    }



    /**
     *  根据所选学生id 获取学习情况统计报表 老师端
     * @param errorRateDto  学生id {@link ErrorRateDto}
     * @return 报表信息
     */
    @Override
    public List<ErrorRateVo> studyReportCorrectRate(ErrorRateDto errorRateDto) {
        /*String groupByType = errorRateDto.getGroupByType();
        switch (groupByType) {
            case "每年":
                errorRateDto.setGroupByType("%Y");
                break;
            case "每月":
                errorRateDto.setGroupByType("%Y-%m");
                break;
            case "每周":
                errorRateDto.setGroupByType("%Y-%u");
                break;
            case "每天":
                errorRateDto.setGroupByType("%Y-%m-%d");
                break;
        }*/
        return  ChapterExercisesTopicMapper.studyReportErrorRate(errorRateDto);
    }

    /**
     *  根据所选学生id 获取学习情况统计报表 习题正确率 老师端
     * @param errorRateDto  学生id {@link ErrorRateDto}  studentId;  subjectId;
     * @return 报表信息
     */
    @Override
    public TopicCorrectRateVo studyReportOfAllTopicCorrectRate(ErrorRateDto errorRateDto) {
        TopicCorrectRateVo data = ChapterExercisesTopicMapper.studyReportOfAllTopicCorrectRate(errorRateDto);
        if (!Objects.isNull(data)){
            NumberFormat numberFormat = NumberFormat.getInstance();
            numberFormat.setMaximumFractionDigits(2);
            String correctRate = numberFormat.format((float) data.getCorrectNum() / (float) (data.getCorrectNum()+data.getErrorNum()));
            String errorRate = numberFormat.format((float) data.getErrorNum() / (float) (data.getCorrectNum()+data.getErrorNum()));
            data.setCorrectRate(Float.parseFloat(correctRate));
            data.setErrorRate(Float.parseFloat(errorRate));
            return data;
        }else {
            return new TopicCorrectRateVo();
        }

    }

    @Override
    public List<ChapterAndKnowledgeVO> getAllWrongChapterWrongQuestionSet(Integer currentUserId, Integer subjectId) {
        List<Integer> knowledgePointIds = getKnowledgePointIds(currentUserId);
        List<ReadKnowledgePointPO> knowledgePoints = knowledgePointMapper.selectBatchIds(knowledgePointIds);

        List<KnowledgeVO> knowledgeVOS = BeanCopierUtil.copy(knowledgePoints, KnowledgeVO.class);
        knowledgeVOS.forEach(item->{
            ReadChapterExercisesPO exercisesPO = chapterExercisesMapper
                    .selectOne(new QueryWrapper<ReadChapterExercisesPO>().eq("student_id", currentUserId).eq("knowledge_id", item.getId()));
            item.setCorrectNum(exercisesPO.getCorrectNum());
            item.setErrorNum(exercisesPO.getErrorNum());
        });

        List<Integer> chapterIds= knowledgePoints
                .stream()
                .map(ReadKnowledgePointPO::getChapterId)
                .distinct()
                .collect(Collectors.toList());
        if (chapterIds.isEmpty())return new ArrayList<>();
        List<ReadChapterPO> chapterPOS = chapterMapper.selectList(new QueryWrapper<ReadChapterPO>().eq("subject_id", subjectId).in("id", chapterIds));

        List<ChapterAndKnowledgeVO> result = BeanCopierUtil.copy(chapterPOS, ChapterAndKnowledgeVO.class);
        result.forEach(item->{
            item.setKnowledge(knowledgeVOS.stream().filter(knowledgeVO -> knowledgeVO.getChapterId().equals(item.getId())).collect(Collectors.toList()));
        });
        return result;
    }
}
